﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Web.Http;
using System.Web.Http.Controllers;
using Common.Logging;
using In.Api.Dto.HisWs;
using Newtonsoft.Json;
using OutDbContext;
using Rmq.Center;
using Senparc.Weixin.MP.TenPayLib;
using User.Api.BizExtensions;
using User.Api.Dto.Bill;
using User.Api.Helpers;
using User.Api.HttpClients;

namespace User.Api.Controllers
{
    public class BillController : ApiController
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(BillController));
        private HzfyWeiXinEntities _ctx;

        private static readonly object OrderNoLocker = new object();
        private static readonly object PayNotifyLocker = new object();
        private static TenPayInfo _tenPayInfo;

        public static TenPayInfo TenPayInfo
        {
            get
            {
                if (_tenPayInfo == null)
                {
                    _tenPayInfo =
                        TenPayInfoCollection.Data[ConfigurationManager.AppSettings["WeixinPay_PartnerId"]];
                }
                return _tenPayInfo;
            }
        }

        protected override void Initialize(HttpControllerContext controllerContext)
        {
            _ctx = new HzfyWeiXinEntities();
            base.Initialize(controllerContext);
        }

        protected override void Dispose(bool disposing)
        {
            _ctx.Dispose();
            base.Dispose(disposing);
        }

        /// <summary>
        /// 获取待缴费单列表
        /// </summary>
        /// <param name="cardId">卡Id</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("GetBillList")]
        public GetBillListResponse GetBillList(int cardId)
        {
            var azUser = AzUser.GetInApi(Request);

            var card = _ctx.HospCard.FirstOrDefault(x => x.Id == cardId && x.WxUserId == azUser.UserId);
            if (card == null)
            {
                return new GetBillListResponse
                {
                    ResultCode = "1",
                    ResultMsg = "找不到就诊卡信息"
                };
            }

            //获取院内webservice
            var request = new GetPrescriptionListRequest();
            request.PatientID = card.PatientId;

            GetPrescriptionListResponse response;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetPrescriptionList", request).Result;
                responseMsg.EnsureSuccessStatusCode();
                response = responseMsg.Content.ReadAsAsync<GetPrescriptionListResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内获取待缴费单列表出错,信息：{0}", JsonConvert.SerializeObject(ex));

                return new GetBillListResponse
                {
                    ResultCode = "2",
                    ResultMsg = "获取缴费单信息超时"
                };
            }

            if (response.ResultCode != "0")
            {
                return new GetBillListResponse
                {
                    ResultCode = "3",
                    ResultMsg = response.ResultDesc
                };
            }
            
            return new GetBillListResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                Bills = response.PrescList
                    .Where(x => DateTime.Parse(x.OrderDate) <= DateTime.Now
                     && x.PrescMoney.ToDecimalOrDefault() > 0)
                    .Select(x => new GetBillListResponse.BillInfo
                    {
                        ClinicNo = x.ClinicNo,
                        PrescMoney = x.PrescMoney.ToDecimalOrDefault().ToString("F2"),
                        OrderDept = x.OrderDept,
                        OrderDate = x.OrderDate,
                        OrderDoctor = x.OrderDoctor,
                        CardNo = card.CardNo,
                        CardType = card.CardType.ToString(),
                    }).ToList()
            };
        }

        /// <summary>
        /// 获取处方单明细
        /// </summary>
        /// <param name="prescNo">处方单No：PrescNo</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("BillOrderPrescription")]
        public GetBillOrderDetailResponse BillOrderPrescription(string orderDate, string cardId)
        {
            var azUser = AzUser.GetInApi(Request);
            var card = _ctx.HospCard.FirstOrDefault(x => x.IsDefault == 1 && x.WxUserId == azUser.UserId);

            var request = new GetPrescriptionDetailRequest();
            request.PatientID = cardId;
            request.StartDate = orderDate;
            request.EndDate = orderDate;
            GetPrescriptionDetailResponse response;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetPrescriptionDetail", request).Result;
                responseMsg.EnsureSuccessStatusCode();
                response = responseMsg.Content.ReadAsAsync<GetPrescriptionDetailResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内获取处方单明细出错,信息：{0}", JsonConvert.SerializeObject(ex));

                return new GetBillOrderDetailResponse
                {
                    ResultCode = "2",
                    ResultMsg = "获取缴费单信息超时"
                };
            }

            if (response.ResultCode != "0")
            {
                return new GetBillOrderDetailResponse
                {
                    ResultCode = "3",
                    ResultMsg = response.ResultDesc
                };
            }

            return new GetBillOrderDetailResponse
            {
                ResultCode = "0",
                ResultMsg = "",

                AdmReasonList = response.AdmReasonList.Select(x => new GetBillOrderDetailResponse.AdmReasonInfo()
                {
                    InsuTypeDR = x.InsuTypeDR,
                    Type = x.Type,
                    PrescMoney = x.PrescMoney,

                    PrescItemList =x.PrescItemList.Select(y => new GetBillOrderDetailResponse.AdmReasonInfo.PrescItemInfo()
                    {
                        ItemName=y.ItemName,
                        Money=y.Money,
                        BillDetails = y.OEOrdItemList
                  .Select(z => new GetBillOrderDetailResponse.AdmReasonInfo.PrescItemInfo.BillDetail()
                  {
                      ItemName = z.NameDesc,
                      Account = z.Qty,
                      Unit = z.Unit,
                      Money = ("0" + z.Account).ToDecimalOrDefault().ToString("F4"),
                      ItemPrice = ("0" + z.ItemPrice).ToDecimalOrDefault().ToString("F4")
                  }).ToList()
                    }).ToList()
                }).ToList(),

            };
        }

        /// <summary>
        /// 生成缴费订单
        /// </summary>
        /// <param name="cardId"></param>
        /// <param name="clinicNo">strGuid</param>
        /// <param name="prescMoney">缴费金额</param>
        /// <param name="orderDept">科室</param>
        /// <param name="orderDate">时间</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("CreateBillOrder")]
        public CreateBillOrderResponse CreateBillOrder(int cardId, string clinicNo, string prescMoney,
            string orderDept, string orderDoctor, string orderDate)
        {
            var azUser = AzUser.GetInApi(Request);

            var card = _ctx.HospCard.FirstOrDefault(x => x.Id == cardId && x.WxUserId == azUser.UserId);
            if (card == null)
            {
                return new CreateBillOrderResponse
                {
                    ResultCode = "1",
                    ResultMsg = "找不到就诊卡信息"
                };
            }

            // 获取消费单明细
            var billDetailRequest = new GetPrescriptionDetailRequest();
            billDetailRequest.PatientID = card.PatientId;
            billDetailRequest.StartDate= orderDate;
            billDetailRequest.EndDate = orderDate;
            billDetailRequest.PrescNo = clinicNo;
            GetPrescriptionDetailResponse billDetailResponse;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetPrescriptionDetail", billDetailRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                billDetailResponse = responseMsg.Content.ReadAsAsync<GetPrescriptionDetailResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内获取缴费单明细Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                return new CreateBillOrderResponse
                {
                    ResultCode = "2",
                    ResultMsg = "获取缴费单明细超时"
                };
            }

            if (billDetailResponse.ResultCode != "0")
            {
                return new CreateBillOrderResponse
                {
                    ResultCode = "2",
                    ResultMsg = billDetailResponse.ResultDesc
                };
            }
            // 为了避免医生 在同一个 就诊流水号 上再次开单造成患者无法支付的情况，对于 未支付 和 缴费成功 的情况我们可以 再次生成订单
            // 未支付但使用了医保的订单，需要医保退费处理
            var dcmPrescMoney = prescMoney.ToDecimalOrDefault();
            var billOrder = _ctx.BillOrder.FirstOrDefault(x =>
                        x.CardNo == card.CardNo && x.OrderDate == orderDate
                        && x.PrescMoney == dcmPrescMoney
                        && x.ClinicNo == clinicNo);
            if (billOrder != null)
            {
                if (billOrder.OrderStatus == BillOrderExtensions.OrderStatus.支付中.ToInt32()
                    || billOrder.OrderStatus == BillOrderExtensions.OrderStatus.支付成功.ToInt32()
                    || billOrder.OrderStatus == BillOrderExtensions.OrderStatus.缴费中.ToInt32())
                {
                    return new CreateBillOrderResponse
                    {
                        ResultCode = "3",
                        ResultMsg = "系统正在处理您的订单请耐心等候，大约需要15分钟"
                    };
                }
                //关闭未支付订单
                else
                {
                    if (billOrder.OrderStatus == BillOrderExtensions.OrderStatus.未支付.ToInt32())
                    {
                        billOrder.OrderStatus = BillOrderExtensions.OrderStatus.支付失败.ToInt32();
                        _ctx.SaveChanges();
                    }
                }
            }

            var newOrderNo = GenerateNewOrderNo();
            var newBillOrder = new BillOrder
            {
                ClinicNo = clinicNo,
                OrderDept = orderDept,
                OrderDoctor = orderDoctor,
                WxUserId = azUser.UserId,
                CardNo = card.PatientId,
                CardType = card.CardType.ToStringOrDefault(),
                OrderNo = newOrderNo,
                OrderDate = orderDate,
                OrderStatus = 0,
                PrescMoney = prescMoney.ToDecimalOrDefault(),
                PayState = BillOrderExtensions.PayState.未付款.ToInt32().ToString(),
                CreateTime = DateTime.Now,
                CardName = card.PatientName
            };
            _ctx.BillOrder.Add(newBillOrder); 
            _ctx.SaveChanges(); 
            foreach (var adm in billDetailResponse.AdmReasonList)
            {
                foreach(var item in adm.PrescItemList)
                {
                    foreach(var OEO in item.OEOrdItemList)
                    {
                        var newBillOrderItem = new BillOrderItem
                        {
                            BillOrderId = newBillOrder.Id,
                            Account = OEO.Qty,
                            ItemPrice = OEO.ItemPrice.ToDecimalOrDefault(),
                            Money = OEO.Account.ToDecimalOrDefault(),
                            Name = OEO.NameDesc,
                            Type = item.ItemName,
                            Unit = OEO.Unit
                        };
                        _ctx.BillOrderItem.Add(newBillOrderItem);
                    }
                }
            }
            _ctx.SaveChanges();

            var response = new CreateBillOrderResponse();
            response.ResultCode = "0";
            response.ResultMsg = "";
            response.OrderId = newBillOrder.Id;
            response.OrderNo = newBillOrder.OrderNo;
            response.YiBaoStatus = newBillOrder.YiBaoStatus.GetValueOrDefault();
            response.YiBaoFailedMsg = newBillOrder.Remark ?? "";
            response.PersonalMoney = newBillOrder.PersonalMoney.GetValueOrDefault().ToString("F2");
            response.YiBaoMoney = newBillOrder.YibaoMoney.GetValueOrDefault().ToString("F2");
            response.Items = new List<CreateBillOrderResponse.BillItem>();
            foreach (var adm in billDetailResponse.AdmReasonList)
            {
                foreach (var item in adm.PrescItemList)
                {
                    foreach (var OEO in item.OEOrdItemList)
                    {
                        response.Items.Add(new CreateBillOrderResponse.BillItem
                        {
                            Account = OEO.Qty,
                            ItemPrice = OEO.ItemPrice.ToDecimalOrDefault().ToString("F2"),
                            Money = OEO.Account.ToDecimalOrDefault().ToString("F2"),
                            Name = OEO.NameDesc,
                            Type = item.ItemName,
                            Unit = OEO.Unit
                        });
                    }
                }
            }
            return response;
        }

        /// <summary>
        /// 支付缴费单
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("PayBill")]
        public PayBillReponse PayBill(int orderId)
        {
            var azUser = AzUser.GetInApi(Request);
            var order = _ctx.BillOrder.IsStatus(BillOrderExtensions.OrderStatus.未支付)
                .FirstOrDefault(x => x.Id == orderId && x.WxUserId == azUser.UserId);
            if (order == null)
            {
                return new PayBillReponse
                {
                    ResultCode = "1",
                    ResultMsg = "找不到缴费单"
                };
            }
            var userobj = _ctx.WxUser.FirstOrDefault(x => x.Id == azUser.UserId);
            var openid = userobj == null ? "" : userobj.OpenId;
            order.OrderStatus = BillOrderExtensions.OrderStatus.支付中.ToInt32();
            _ctx.SaveChanges();
            
            // RMQ 16分钟后如果还是支付中则设置支付失败
            var payingTimeoutProducer = new OrderPayingTimeoutProducer();
            payingTimeoutProducer.Publish(new OrderPayingTimeoutMsg
            {
                OrderType = OrderType.门诊缴费订单,
                OrderId = order.Id
            }, 16 * 60 * 1000);
          
            //组织 微信 js 支付方法 getBrandWCPayRequest 的参数
            var payStartTime = System.DateTime.Now.ToString("yyyyMMddHHmmss");
            var payExpireTime = System.DateTime.Now.AddMinutes(15).ToString("yyyyMMddHHmmss");
           
            var payFee  = (order.PrescMoney.GetValueOrDefault() * 100).ToInt32().ToString();
            
            var superUserIds = ConfigurationManager.AppSettings["OpenIdsForPayMin"]
                .Split(" , ", StringSplitOptions.RemoveEmptyEntries);
            if (superUserIds.Contains(order.WxUserId.ToString()))
            {
                payFee = "1";
            }

            var result = WeixinPayV3Helper.ComposeJsApiParameter("JSAPI", "就诊缴费", "BL" + order.OrderNo,
             payFee, GetClientIp(), payStartTime, payExpireTime, "Bill/PaySucceed", openid);

            return new PayBillReponse
            {
                ResultCode = result.ResultCode,
                ResultMsg = result.ResultMsg??"",
                PayString = result.Parameter ?? ""
            };
        }

        /// <summary>
        /// 用户取消支付
        /// </summary>
        /// <param name="orderId">订单id</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("PayFailed")]
        public PayFailedResponse PayFailed(int orderId)
        {
            var azUser = AzUser.GetInApi(Request);

            var order = _ctx.BillOrder.IsStatus(BillOrderExtensions.OrderStatus.支付中)
                .FirstOrDefault(x => x.WxUserId == azUser.UserId && x.Id == orderId);
            if (order == null)
            {
                return new PayFailedResponse
                {
                    ResultCode = "1",
                    ResultMsg = "订单不存在"
                };
            }

            order.OrderStatus = BillOrderExtensions.OrderStatus.支付失败.ToInt32();
            _ctx.SaveChanges();
            
            return new PayFailedResponse
            {
                ResultCode = "0",
                ResultMsg = ""
            };
        }
         
        /// <summary>
        /// 查询缴费执行状态
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("GetBillStatus")]
        public GetBillStatusResponse GetBillStatus(int orderId)
        {
            var azUser = AzUser.GetInApi(Request);
            var order = _ctx.BillOrder.FirstOrDefault(x => x.Id == orderId && x.WxUserId == azUser.UserId);
            if (order == null)
            {
                return new GetBillStatusResponse
                {
                    ResultCode = "1",
                    ResultMsg = "订单不存在"
                };
            }

            if (order.OrderStatus == BillOrderExtensions.OrderStatus.缴费中.ToInt32()
                || order.OrderStatus == BillOrderExtensions.OrderStatus.支付中.ToInt32()
                || order.OrderStatus == BillOrderExtensions.OrderStatus.支付成功.ToInt32())
            {
                return new GetBillStatusResponse
                {
                    ResultCode = "0",
                    ResultMsg = "",
                    BillStatus = "2",
                    FailedMsg = ""
                };
            }

            if (order.OrderStatus == BillOrderExtensions.OrderStatus.缴费成功.ToInt32())
            {
                return new GetBillStatusResponse
                {
                    ResultCode = "0",
                    ResultMsg = (order.Remark ?? "").IndexOf("佑元庄", StringComparison.Ordinal) >= 0
                        ? (order.Remark ?? "") : "",
                    BillStatus = "0",
                    FailedMsg = ""
                };
            }

            return new GetBillStatusResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                BillStatus = "1",
                FailedMsg = ""
            };
        }

        /// <summary>
        /// 生成挂号订单号
        /// </summary>
        /// <returns></returns>
        public static string GenerateNewOrderNo()
        {
            var orderNo = "WX" + DateTime.Now.Date.ToString("yyyyMMdd");
            lock (OrderNoLocker)
            {
                orderNo += (DateTime.Now - DateTime.Now.Date).TotalMilliseconds.ToString("00000000");
                Thread.Sleep(1);
            }

            return orderNo;
        }

        public string GetClientIp()
        {
            if (Request.Properties.ContainsKey("MS_HttpContext"))
            {
                string ip = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                //判断是否有代理服务器
                if (string.IsNullOrEmpty(ip))
                {
                    //没有代理服务器,如果有代理服务器获取的是代理服务器的IP
                    ip = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                }

                string pattrn = @"(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])";
                if (!string.IsNullOrEmpty(ip) && System.Text.RegularExpressions.Regex.IsMatch(ip, pattrn))
                {
                    return ip;
                }

                return "127.0.0.1";
            }
            else
            {
                return "127.0.0.1";
            }
        }

        /// <summary>
        /// 微信支付通知回调
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [ActionName("PaySucceed")]
        public HttpResponseMessage PaySucceed()
        {

            var result = WeixinPayV3Helper.ParsePayNotify(Request.RequestUri, Request.Content.ReadAsStringAsync().Result.Copy());
            if (result.ResultCode != "0")
            {
                #region 记录验证失败的支付通知

                var wxPayNotifyLog = new WxPayNotifyLog();
                wxPayNotifyLog.Uri = Request.RequestUri.AbsoluteUri;
                wxPayNotifyLog.IsVerified = 2;
                wxPayNotifyLog.RecCreateDt = DateTime.Now;
                _ctx.WxPayNotifyLog.Add(wxPayNotifyLog);
                _ctx.SaveChanges();

                #endregion
                return new HttpResponseMessage
                {
                    StatusCode = HttpStatusCode.OK,
                    Content = new StringContent(result.FailResponse)
                };
            }
            var transactionId = result.PayOrder.TransactionId;

            lock (PayNotifyLocker)
            {
                try
                {
                    if (
                        _ctx.WxPayNotifyLog.Any(
                            x => x.TransactionId == transactionId && x.TradeState == 0 && x.IsVerified == 1))
                    {
                        return new HttpResponseMessage
                        {
                            StatusCode = HttpStatusCode.OK,
                            Content = new StringContent(result.SuccessResponse)
                        };
                    }
                    else
                    {
                        if (result.ResultCode == "0") //成功
                        {
                            if (result.PayOrder.TradeState == "0")
                            {
                                //处理订单 并记录日志
                                if (result.PayOrder.OutTradeNo.StartsWith("BL"))
                                {
                                    var orderNo = result.PayOrder.OutTradeNo.Substring(2);
                                    var order = _ctx.BillOrder.FirstOrDefault(x => x.OrderNo == orderNo);
                                    if (order != null)
                                    {
                                        //订单状态为待支付，执行his缴费操作
                                        if (order.OrderStatus == BillOrderExtensions.OrderStatus.支付中.ToInt32())
                                        {
                                            order.PayState = BillOrderExtensions.PayState.已付款.ToInt32().ToString();
                                            order.PayTime = DateTime.ParseExact(result.PayOrder.TimeEnd,
                                                "yyyyMMddHHmmss",
                                                CultureInfo.CurrentCulture);
                                            order.WxTransactionId = transactionId;
                                            order.OrderStatus = BillOrderExtensions.OrderStatus.支付成功.ToInt32();
                                            _ctx.SaveChanges();

                                            // RMQ 执行缴费操作
                                            var pickupingProducer = new OrderPickupingProducer();
                                            pickupingProducer.Publish(new OrderPickupingMsg
                                            {
                                                OrderType = Rmq.Center.OrderType.门诊缴费订单,
                                                OrderId = order.Id
                                            });
                                        }
                                        //如果订单状态为支付失败（订单15分钟已关闭，用户），或者His缴费失败 added by wesley
                                        else if (order.OrderStatus == BillOrderExtensions.OrderStatus.缴费失败.ToInt32() ||
                                                 order.OrderStatus == BillOrderExtensions.OrderStatus.支付失败.ToInt32())
                                        {
                                            //执行退款操作
                                            var refundingProducer = new OrderRefundingPickupFailedProducer();
                                            refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                                            {
                                                OrderType = OrderType.门诊缴费订单,
                                                OrderId = order.Id
                                            });
                                        }
                                    }
                                }
                            }

                        }

                        //记录通知日志
                        var orderNotifyLog = new WxPayNotifyLog
                        {
                            ServiceVersion = result.PayOrder.ServiceVersion,
                            Attach = result.PayOrder.Attach,
                            BankBillNo = result.PayOrder.BankBillNo,
                            BankType = result.PayOrder.BankType,
                            BuyerAlias = result.PayOrder.BuyerAlias,
                            Discount = result.PayOrder.Discount.ToNullableInt32(),
                            //FeeType = result.PayOrder.FeeType.ToNullableInt32(),
                            InputCharset = result.PayOrder.InputCharset,
                            NotifyId = result.PayOrder.NotifyId,
                            SignType = result.PayOrder.SignType,
                            Sign = result.PayOrder.Sign,
                            SignKeyIndex = result.PayOrder.SignKeyIndex.ToNullableInt32(),
                            //TradeMode = result.PayOrder.TradeMode.ToNullableInt32(),
                            TradeState = result.PayOrder.TradeState.ToNullableInt32(),
                            PayInfo = result.PayOrder.PayInfo,
                            Partner = result.PayOrder.Partner,
                            TotalFee = result.PayOrder.TotalFee.ToNullableInt32(),
                            TransactionId = result.PayOrder.TransactionId,
                            OutTradeNo = result.PayOrder.OutTradeNo,
                            TimerEnd = result.PayOrder.TimeEnd,
                            TransportFee = result.PayOrder.TransportFee.ToNullableInt32(),
                            ProductFee = result.PayOrder.ProductFee.ToNullableInt32(),
                            PostAppId = result.PayUser.AppId,
                            PostTimeStamp = result.PayUser.TimeStamp,
                            PostNonceStr = result.PayUser.NonceStr,
                            PostOpenId = result.PayUser.OpenId,
                            PostAppSignature = result.PayUser.AppSignature,
                            PostIsSubscribe = result.PayUser.IsSubscribe,
                            Uri = Request.RequestUri.AbsoluteUri,
                            IsVerified = 1,
                            RecCreateDt = DateTime.Now
                        };
                        _ctx.WxPayNotifyLog.Add(orderNotifyLog);
                        _ctx.SaveChanges();

                        return new HttpResponseMessage
                        {
                            StatusCode = HttpStatusCode.OK,
                            Content = new StringContent(result.SuccessResponse)
                        };
                    }
                }
                catch (System.Data.SqlClient.SqlException sqlEx)
                {
                    Logger.ErrorFormat("Bill PaySuccessed SqlException Error:{0}", JsonConvert.SerializeObject(sqlEx));
                }
                catch (Exception e)
                {
                    Logger.ErrorFormat("Bill PaySuccessed Error:{0}", JsonConvert.SerializeObject(e));

                }
            }

            #region 记录验证失败的支付通知

            var unverifiedNotifyLog = new WxPayNotifyLog();
            unverifiedNotifyLog.Uri = Request.RequestUri.AbsoluteUri;
            unverifiedNotifyLog.IsVerified = 0;
            unverifiedNotifyLog.RecCreateDt = DateTime.Now;
            _ctx.WxPayNotifyLog.Add(unverifiedNotifyLog);
            _ctx.SaveChanges();

            #endregion

            return new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent(result.FailResponse)
            };


        }



        /// <summary>
        /// 扫码支付通知回调
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [ActionName("SCPaySucceed")]
        public HttpResponseMessage SCPaySucceed()
        {
            Logger.ErrorFormat("Bill PaySuccessed SqlException Error:{0}", 1);
            var result = WeixinPayV3Helper.ParsePayNotify(Request.RequestUri, Request.Content.ReadAsStringAsync().Result.Copy());
            Logger.ErrorFormat("Bill PaySuccessed SqlException Error:{0}", result.ResultCode);
            if (result.ResultCode != "0")
            {
                #region 记录验证失败的支付通知

                var wxPayNotifyLog = new WxPayNotifyLog();
                wxPayNotifyLog.Uri = Request.RequestUri.AbsoluteUri;
                wxPayNotifyLog.IsVerified = 2;
                wxPayNotifyLog.RecCreateDt = DateTime.Now;
                _ctx.WxPayNotifyLog.Add(wxPayNotifyLog);
                _ctx.SaveChanges();

                #endregion
                return new HttpResponseMessage
                {
                    StatusCode = HttpStatusCode.OK,
                    Content = new StringContent(result.FailResponse)
                };
            }
            var transactionId = result.PayOrder.TransactionId;
            Logger.ErrorFormat("Bill PaySuccessed SqlException Error:{0}", transactionId);
            lock (PayNotifyLocker)
            {
                if (_ctx.WxPayNotifyLog.Any(x => x.TransactionId == transactionId && x.TradeState == 0 && x.IsVerified == 1))
                {
                    return new HttpResponseMessage
                    {
                        StatusCode = HttpStatusCode.OK,
                        Content = new StringContent(result.SuccessResponse)
                    };
                }
                if (result.ResultCode == "0")//成功
                {

                    if (result.PayOrder.TradeState == "0")
                    {
                        var outTradeNo = result.PayOrder.OutTradeNo;
                        /*
                         * 扫码支付订单号规则：
                         * 解析：SC = Scan Code 单词首字母
                         *       AP = Appointment 预约  简写
                         *       BL = Bill 账单 简写
                        */
                        if (outTradeNo.StartsWith("SC")) //扫码支付
                        {
                            var orderNo = outTradeNo.Substring(2);
                            var order = _ctx.BillOrder.FirstOrDefault(x => x.OrderNo == orderNo);
                            if (order != null)
                            {
                                //订单状态为待支付，执行his缴费操作
                                if (order.OrderStatus == BillOrderExtensions.OrderStatus.支付中.ToInt32())
                                {
                                    order.PayState = BillOrderExtensions.PayState.已付款.ToInt32().ToString();
                                    order.PayTime = DateTime.ParseExact(result.PayOrder.TimeEnd, "yyyyMMddHHmmss",
                                        CultureInfo.CurrentCulture);
                                    order.WxTransactionId = transactionId;
                                    order.OrderStatus = BillOrderExtensions.OrderStatus.缴费成功.ToInt32();
                                    _ctx.SaveChanges();

                                    // RMQ 执行缴费操作
                                    //var pickupingProducer = new OrderPickupingProducer();
                                    //pickupingProducer.Publish(new OrderPickupingMsg
                                    //{
                                    //    OrderType = Rmq.Center.OrderType.扫码支付订单,
                                    //    OrderId = order.Id
                                    //});
                                }
                                //如果订单状态为支付失败（订单15分钟已关闭，用户），或者His缴费失败 added by wesley
                                //else if (order.OrderStatus == BillOrderExtensions.OrderStatus.缴费失败.ToInt32() ||
                                //         order.OrderStatus == BillOrderExtensions.OrderStatus.支付失败.ToInt32())
                                //{
                                //    ////执行退款操作
                                //    //var refundingProducer = new OrderRefundingPickupFailedProducer();
                                //    //refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                                //    //{
                                //    //    OrderType = OrderType.门诊缴费订单,
                                //    //    OrderId = order.Id
                                //    //});
                                //    order.PayState = BillOrderExtensions.PayState.已付款.ToInt32().ToString();
                                //    order.PayTime = DateTime.ParseExact(result.PayOrder.TimeEnd, "yyyyMMddHHmmss",
                                //        CultureInfo.CurrentCulture);
                                //    order.WxTransactionId = transactionId;
                                //    //order.OrderStatus = BillOrderExtensions.OrderStatus.支付成功.ToInt32();
                                //    _ctx.SaveChanges();
                                //    // RMQ 门诊缴费订单状态查询
                                //    var unapptingProducer = new OrderPickupingChkProducer();
                                //    unapptingProducer.Publish(new OrderPickupingChkMsg
                                //    {
                                //        OrderType = Rmq.Center.OrderType.门诊缴费订单,
                                //        OrderId = order.Id
                                //    }, 6 * 60 * 1000);
                                //}
                            }
                        }

                    }
                    //记录通知日志
                    var orderNotifyLog = new WxPayNotifyLog
                    {
                        ServiceVersion = result.PayOrder.ServiceVersion,
                        Attach = result.PayOrder.Attach,
                        BankBillNo = result.PayOrder.BankBillNo,
                        BankType = result.PayOrder.BankType,
                        BuyerAlias = result.PayOrder.BuyerAlias,
                        Discount = result.PayOrder.Discount.ToNullableInt32(),
                        //FeeType = result.PayOrder.FeeType.ToNullableInt32(),
                        InputCharset = result.PayOrder.InputCharset,
                        NotifyId = result.PayOrder.NotifyId,
                        SignType = result.PayOrder.SignType,
                        Sign = result.PayOrder.Sign,
                        SignKeyIndex = result.PayOrder.SignKeyIndex.ToNullableInt32(),
                        //TradeMode = result.PayOrder.TradeMode.ToNullableInt32(),
                        TradeState = result.PayOrder.TradeState.ToNullableInt32(),
                        PayInfo = result.PayOrder.PayInfo,
                        Partner = result.PayOrder.Partner,
                        TotalFee = result.PayOrder.TotalFee.ToNullableInt32(),
                        TransactionId = result.PayOrder.TransactionId,
                        OutTradeNo = result.PayOrder.OutTradeNo,
                        TimerEnd = result.PayOrder.TimeEnd,
                        TransportFee = result.PayOrder.TransportFee.ToNullableInt32(),
                        ProductFee = result.PayOrder.ProductFee.ToNullableInt32(),
                        PostAppId = result.PayUser.AppId,
                        PostTimeStamp = result.PayUser.TimeStamp,
                        PostNonceStr = result.PayUser.NonceStr,
                        PostOpenId = result.PayUser.OpenId,
                        PostAppSignature = result.PayUser.AppSignature,
                        PostIsSubscribe = result.PayUser.IsSubscribe,
                        Uri = Request.RequestUri.AbsoluteUri,
                        IsVerified = 1,
                        RecCreateDt = DateTime.Now
                    };

                    _ctx.WxPayNotifyLog.Add(orderNotifyLog);
                    _ctx.SaveChanges();
                    return new HttpResponseMessage
                    {
                        StatusCode = HttpStatusCode.OK,
                        Content = new StringContent(result.SuccessResponse)
                    };
                }
            }
            #region 记录验证失败的支付通知

            var unverifiedNotifyLog = new WxPayNotifyLog();
            unverifiedNotifyLog.Uri = Request.RequestUri.AbsoluteUri;
            unverifiedNotifyLog.IsVerified = 0;
            unverifiedNotifyLog.RecCreateDt = DateTime.Now;
            _ctx.WxPayNotifyLog.Add(unverifiedNotifyLog);
            _ctx.SaveChanges();

            #endregion

            return new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent(result.FailResponse)
            };


        }
    }
}
